home *** CD-ROM | disk | FTP | other *** search
- ;=============================================================================
- ; LITES displays the realtime status of the UART's DTR, RTS, CTS, DSR, DCD,
- ; and RI lines as well as its Baud rate and data format settings. Syntax is:
- ; LITES [comport] [U]
- ; where comport is a number indicating which COM port is to be monitored,
- ; and U uninstalls the program from memory.
- ;=============================================================================
- CODE SEGMENT PARA PUBLIC 'CODE'
- ASSUME CS:CODE
- ORG 100H
- BEGIN: JMP INITIALIZE
-
- PROGRAM DB "LITES 1.0 (c) 1989 Ziff Communications Co.",13,10
- AUTHOR DB "PC Magazine ",254," Jeff Prosise",13,10
- HOTKEY DB "Hotkey is Alt-L",32,32,32,13,10,"$"
-
- ;-----------------------------------------------------------------------------
- ; Patch points to modify the program's operation.
- ;-----------------------------------------------------------------------------
- KEYCODE DB 26H ;scan code for "L" key
- VIDEO_ATTR DB 70H ;status line video attribute
- ROWNUM DB 0 ;row number of status line
- COL_OFFSET DB 0 ;offset from right margin
- TICKS DB 2 ;ticks between refreshes
- COMPORT DW 0 ;COM port designator (COM1)
-
- ;-----------------------------------------------------------------------------
- ; Other program variables.
- ;-----------------------------------------------------------------------------
- INT09H DD ? ;interrupt 9h vector
- INT08H DD ? ;interrupt 8h vector
- COUNTER DB 0FFH ;refresh counter
-
- PINS DB ? ;bit 0 = DTR, 1 = RTS
- ; 2 = CTS, 3 = DSR
- ; 4 = RI, 5 = DCD
-
- BAUDRATE DW ? ;Baud rate
- PARITY DB ? ;parity setting
- DATABITS DB ? ;number of data bits
- STOPBITS DB ? ;number of stop bits
-
- VIDEOSEG DW ? ;video segment address
- VIDEOADDR DW ? ;video offset address
- SYNCFLAG DB ? ;0 = no video sync, 1 = sync
-
- PINTEXT DB "DTRRTSCTSDSRRI",32,"DCD"
-
- ;=============================================================================
- ; KBINT intercepts and handles the keyboard interrupt 9h.
- ;=============================================================================
- KBINT PROC FAR
-
- PUSHF ;save flags
- PUSH AX ;save AX
-
- STI ;interrupts on
- IN AL,60H ;get scan code from keyboard
- CMP AL,CS:[KEYCODE] ;exit to BIOS if it's not
- JNE NOT_HOT ; the hotkey
- MOV AH,2 ;get keyboard shift state
- INT 16H
- AND AL,0FH ;mask off the upper 4 bits
- CMP AL,8 ;exit if Alt isn't held down
- JNE NOT_HOT
- MOV AH,0FH ;get current video mode
- INT 10H
- CMP AL,7 ;abort if not in text mode
- JE RESET
- CMP AL,4
- JB RESET
- NOT_HOT: POP AX ;exit to BIOS int 9 handler
- POPF
- JMP CS:INT09H
- ;
- ;Reset the keyboard controller and interrupt controller.
- ;
- RESET: CLI ;interrupts off
- IN AL,61H ;reset the keyboard controller
- MOV AH,AL
- OR AL,80H
- OUT 61H,AL
- XCHG AH,AL
- MOV AL,20H ;signal EOI to interrupt
- OUT 20H,AL ; controller
- STI ;interrupts back on
- PUSH BX ;save registers
- PUSH CX
- PUSH DX
- PUSH SI
- PUSH DI
- PUSH DS
- PUSH ES
- PUSH BP
- ;
- ;Deactivate the status line if it is currently displayed.
- ;
- CMP CS:[COUNTER],0FFH ;branch if status line is
- JE SETVIDEO ; dormant
- MOV CS:[COUNTER],0FFH ;disable counter
- MOV AX,CS ;point DS:SI to buffer
- MOV DS,AX
- MOV SI,OFFSET INITIALIZE
- MOV ES,CS:[VIDEOSEG] ;point ES:DI to video memory
- MOV DI,CS:[VIDEOADDR]
- MOV CX,32
- CALL VIDEO_XFER ;erase the status line
- JMP SHORT KB_EXIT
- ;
- ;Initialize video parameters.
- ;
- SETVIDEO: MOV CS:[VIDEOSEG],0B800H ;set default video parms
- MOV CS:[SYNCFLAG],0
- MOV AX,40H ;point ES to BIOS data
- MOV ES,AX ; area
- TEST BYTE PTR ES:[63H],20H ;set video segment value
- JZ COLOR ; (monochrome or color)
- MOV CS:[VIDEOSEG],0B000H
- JMP SHORT NOSYNC
- COLOR: MOV AH,12H ;if a color adapter is
- MOV BL,10H ; detected, determine
- INT 10H ; whether or not it's
- CMP BL,10H ; a CGA and set SYNCFLAG
- JNE NOSYNC ; if it is
- MOV CS:[SYNCFLAG],1
- NOSYNC: MOV AX,ES:[4AH] ;calculate offset address
- SHL AX,1 ; within video segment
- MOV BL,CS:[ROWNUM] ;multiply number of columns
- MUL BL ; by row number
- MOV BX,ES:[4AH] ;add column offset
- SUB BL,32
- SUB BL,CS:[COL_OFFSET]
- SHL BL,1
- ADD AX,BX
- ADD AX,ES:[4EH] ;add page address
- MOV CS:[VIDEOADDR],AX ;store it
- ;
- ;Save the portion of the screen that will be overwritten by the status line.
- ;
- MOV DS,CS:[VIDEOSEG] ;point DS:SI to video memory
- MOV SI,CS:[VIDEOADDR]
- MOV AX,CS ;point ES:DI to save buffer
- MOV ES,AX
- MOV DI,OFFSET INITIALIZE
- MOV CX,32
- CALL VIDEO_XFER ;block move
- ;
- ;Activate the status line, restore registers, and exit.
- ;
- MOV AL,CS:[TICKS] ;enable counter
- MOV CS:[COUNTER],AL
- KB_EXIT: POP BP ;restore registers
- POP ES
- POP DS
- POP DI
- POP SI
- POP DX
- POP CX
- POP BX
- POP AX ;restore AX and flags
- POPF
- IRET
- KBINT ENDP
-
- ;=============================================================================
- ; TIMERINT intercepts and handles the timer tick interrupt 8h.
- ;=============================================================================
- TIMERINT PROC FAR
- PUSHF ;push flags for int call
- CALL CS:INT08H ;call old interrupt handler
- CMP CS:[COUNTER],0FFH ;exit if status line is
- JE TIMER_EXIT ; dormant
- DEC CS:[COUNTER] ;decrement timer
- JNZ TIMER_EXIT ;exit if nonzero
- PUSH AX
- MOV AL,CS:[TICKS] ;reset counter
- MOV CS:[COUNTER],AL
- PUSH BX ;save remaining registers
- PUSH CX
- PUSH DX
- PUSH SI
- PUSH DI
- PUSH DS
- PUSH ES
- STI ;enable interrupts
- CALL SETPARMS ;set output variables
- CALL REFRESH ;refresh the status display
- POP ES ;restore registers and exit
- POP DS
- POP DI
- POP SI
- POP DX
- POP CX
- POP BX
- POP AX
- TIMER_EXIT: IRET ;exit
- TIMERINT ENDP
-
- ;-----------------------------------------------------------------------------
- ; SETPARMS is called by TIMERINT to set UART parameter values.
- ;-----------------------------------------------------------------------------
- PSETTINGS DB "NONE"
- DLAB_REG DB ?
-
- SETPARMS PROC NEAR
- MOV DX,CS:[COMPORT] ;get UART base address
- ADD DX,3 ;point DX to Data Format
- PUSH DX
- IN AL,DX ;read Data Format byte
- MOV CS:[DLAB_REG],AL ;save it
- OR AL,80H ;set DLAB
- OUT DX,AL
- SUB DX,3 ;read divisor LSB
- IN AL,DX
- MOV BL,AL
- INC DX
- IN AL,DX ;read divisor MSB
- MOV BH,AL
- OR BX,BX ;don't divide if BX = 0
- JNZ SP1
- MOV WORD PTR CS:[BAUDRATE],0
- JMP SHORT SP2
- SP1: MOV AX,0C200H ;calculate Baud rate from
- MOV DX,1 ; clock and divisor
- DIV BX
- MOV CS:[BAUDRATE],AX ;save it
- SP2: POP DX ;restore Data Format register
- MOV AL,CS:[DLAB_REG]
- OUT DX,AL
- ;
- ;Determine what the parity, data bits, and stop bits settings are.
- ;
- MOV AL,CS:[DLAB_REG] ;data bits in bits 0 and 1
- AND AL,3
- ADD AL,5
- MOV CS:[DATABITS],AL
- MOV AL,CS:[DLAB_REG] ;stop bits in bit 2
- SHR AL,1
- SHR AL,1
- AND AL,1
- ADD AL,1
- MOV CS:[STOPBITS],AL
- MOV BL,CS:[DLAB_REG] ;parity in bits 3 and 4
- MOV CL,3
- SHR BL,CL
- AND BL,3
- XOR BH,BH
- MOV AL,BYTE PTR CS:[PSETTINGS][BX]
- MOV CS:[PARITY],AL
- ;
- ;Determine the states of the CTS, DSR, DCD, and RI input pins.
- ;
- MOV DX,CS:[COMPORT] ;point DX to Modem Status
- ADD DX,6
- IN AL,DX ;read register
- AND AL,0F0H ;mask off the lower 4 bits
- SHR AL,1 ;then save them
- SHR AL,1
- MOV CS:[PINS],AL
- ;
- ;Determine the states of the RTS and DTR output pins.
- ;
- SUB DX,2 ;point DX to Modem Control
- IN AL,DX ;read register
- AND AL,3 ;strip the upper 6 bits
- OR CS:[PINS],AL ;store in PINS byte
- RET
- SETPARMS ENDP
-
- ;-----------------------------------------------------------------------------
- ; REFRESH is called by TIMERINT to display the status line.
- ;-----------------------------------------------------------------------------
- REFRESH PROC NEAR
- MOV AX,CS ;copy the underlying line
- MOV DS,AX ; into the status buffer
- MOV ES,AX
- MOV SI,OFFSET INITIALIZE
- MOV DI,OFFSET INITIALIZE + 64
- MOV CX,32
- CLD
- REP MOVSW
- ;
- ;Construct the portion of the string pertaining to the 6 pins.
- ;
- MOV SI,OFFSET PINTEXT ;point SI to text
- MOV DI,OFFSET INITIALIZE + 64 ;point DI to buffer
- MOV BL,1
- MOV AH,CS:[VIDEO_ATTR]
- MOV CX,6 ;6 pins to test
- RLOOP1: PUSH CX
- PUSH SI
- PUSH DI
- TEST CS:[PINS],BL ;copy pin name to buffer if
- JZ PINLOW ; corresponding bit is set
- MOV CX,3
- RLOOP2: LODSB
- STOSW
- LOOP RLOOP2
- PINLOW: POP DI
- POP SI
- SHL BL,1
- ADD SI,3
- ADD DI,8
- POP CX
- LOOP RLOOP1 ;loop unitl all 6 are done
- ;
- ;Add Baud rate, parity, data bits, and stop bits indicators to the string.
- ;
- MOV AX,CS:[BAUDRATE] ;Baud rate
- CALL BIN2ASC
- MOV DI,OFFSET INITIALIZE + 64 + 58
- MOV AL,CS:[PARITY] ;parity
- MOV AH,CS:[VIDEO_ATTR]
- STOSW
- MOV AL,CS:[DATABITS] ;data bits
- ADD AL,30H
- STOSW
- MOV AL,CS:[STOPBITS] ;stop bits
- ADD AL,30H
- STOSW
- ;
- ;Display the status string.
- ;
- MOV SI,OFFSET INITIALIZE + 64
- MOV ES,CS:[VIDEOSEG]
- MOV DI,CS:[VIDEOADDR]
- MOV CX,32
- CALL VIDEO_XFER
- RET
- REFRESH ENDP
-
- ;-----------------------------------------------------------------------------
- ; VIDEO_XFER transfers a block of data to or from the video buffer.
- ; Entry: DS:SI - source
- ; ES:DI - destination
- ; CX - number of words
- ;-----------------------------------------------------------------------------
- VIDEO_XFER PROC NEAR
- CLD ;clear DF
- TEST CS:[SYNCFLAG],1 ;don't wait if this isn't
- JZ NOWAIT ; a CGA
- MOV DX,3DAH ;wait if it is
- MWAIT1: IN AL,DX ;wait for non-retrace period
- TEST AL,8
- JNZ MWAIT1
- MWAIT2: IN AL,DX ;wait for the next vertical
- TEST AL,8 ; retrace
- JZ MWAIT2
- NOWAIT: CLI ;interrupts off
- REP MOVSW ;block move
- STI ;interrupts back on
- RET
- VIDEO_XFER ENDP
-
- ;-----------------------------------------------------------------------------
- ; BIN2ASC converts a single binary word value into its ASCII decimal
- ; equivalent and writes it to the designated output buffer.
- ; Entry: AX - binary value
- ; ES:DI - destination
- ;-----------------------------------------------------------------------------
- BASE DW 10 ;base 10 divisor
-
- BIN2ASC PROC NEAR
- XOR CX,CX ;zero digit counter
- BALOOP1: INC CX ;increment counter
- XOR DX,DX
- DIV CS:[BASE] ;divide by base
- PUSH DX ;save remainder on stack
- OR AX,AX ;loop until quotient is zero
- JNZ BALOOP1
- BALOOP2: POP AX ;pull digits back off the
- ADD AL,30H ; stack and output them
- MOV AH,CS:[VIDEO_ATTR]
- STOSW
- LOOP BALOOP2
- RET
- BIN2ASC ENDP
-
- ;=============================================================================
- ; INITIALIZE installs or uninstalls the program.
- ;=============================================================================
- ERRMSG1 DB "Usage: LITES [comport] [U]$"
- ERRMSG2 DB "Not Installed$"
- ERRMSG3 DB "Cannot Uninstall$"
- ERRMSG4 DB "Already Installed$"
- ERRMSG5 DB "Invalid COM Port$"
- OUTTEXT DB "Uninstalled$"
- INSTALLED DB 0
-
- INITIALIZE PROC NEAR
- ASSUME CS:CODE, DS:CODE
- ;
- ;See if a copy of LITES is already resident in memory.
- ;
- CLD ;clear DF for string ops
- MOV WORD PTR [BEGIN],0 ;initialize fingerprint
- XOR BX,BX ;zero BX for start
- MOV AX,CS ;keep CS value in AX
- INIT1: INC BX ;increment search segment value
- MOV ES,BX
- CMP AX,BX ;not installed if current
- JE PARSE1 ; segment is reached
- MOV SI,OFFSET BEGIN ;search this segment for ASCII
- MOV DI,SI ; fingerprint
- MOV CX,16
- REPE CMPSB
- JNE INIT1 ;loop back if not found
- MOV INSTALLED,1 ;set installed flag
- ;
- ;Parse the command line for entries.
- ;
- PARSE1: MOV SI,81H ;point SI to command line
- PARSE2: LODSB ;get a character
- CMP AL,20H ;skip it if it's a space
- JE PARSE2
- CMP AL,0DH ;exit loop when a carriage
- JE INSTALL ; return is encountered
- CMP AL,"0" ;branch if numeral is found
- JB ERROR1
- CMP AL,"9"
- JBE CHECK_COM
- AND AL,0DFH ;capitalize the character
- CMP AL,"U" ;branch to uninstall code if
- JE UNINSTALL ; character is a "U"
- ;
- ;An error was encountered in parsing. Display error message and exit.
- ;
- ERROR1: MOV DX,OFFSET ERRMSG1 ;load message address
- ERROR2: MOV AH,9 ;display error message
- INT 21H
- MOV AX,4C01H ;exit with ERRORLEVEL = 1
- INT 21H
- ;
- ;Make sure the COM port entered on the command line exists.
- ;
- CHECK_COM: SUB AL,"1" ;normalize the entry
- MOV BL,AL ;save it
- INT 11H ;determine number of COM
- SHR AH,1 ; ports installed
- AND AH,07H
- MOV DX,OFFSET ERRMSG5
- CMP AH,BL ;exit on error if COM port
- JNA ERROR2 ; number is invalid
- MOV BYTE PTR COMPORT,BL ;save port designator
- JMP SHORT INSTALL ;go to install routine
- ;
- ;Uninstall the program.
- ;
- UNINSTALL: MOV DX,OFFSET ERRMSG2 ;error if program isn't
- CMP INSTALLED,0 ; installed
- JE ERROR2
- CALL REMOVE ;call uninstall routine
- MOV DX,OFFSET ERRMSG3 ;error if uninstall failed
- JC ERROR2
- MOV DX,OFFSET OUTTEXT ;display "Uninstalled"
- MOV AH,9 ; message
- INT 21H
- MOV AX,4C00H ;exit with ERRORLEVEL = 0
- INT 21H
- ;
- ;Make sure LITES isn't already installed, then get the UART base address.
- ;
- INSTALL: MOV DX,OFFSET ERRMSG4 ;exit on error if program
- CMP INSTALLED,0 ; is already installed
- JNE ERROR2
- MOV AX,40H ;get UART address from BIOS
- MOV ES,AX ; data area using the port
- XOR DI,DI ; number as an index into
- MOV BX,COMPORT ; the table
- SHL BX,1
- MOV AX,WORD PTR ES:[DI][BX]
- MOV COMPORT,AX
- ;
- ;Hook into interrupts 9h and 8h and deallocate the environment block.
- ;
- MOV AX,3509H ;save old interrupt 9h vector
- INT 21H
- MOV WORD PTR INT09H,BX
- MOV WORD PTR INT09H[2],ES
- MOV AX,2509H ;then set the new 9h vector
- MOV DX,OFFSET KBINT
- INT 21H
- MOV AX,3508H ;save old interrupt 8h vector
- INT 21H
- MOV WORD PTR INT08H,BX
- MOV WORD PTR INT08H[2],ES
- MOV AX,2508H ;then set the new 8h vector
- MOV DX,OFFSET TIMERINT
- INT 21H
- MOV AX,DS:[2CH] ;deallocate the program's
- MOV ES,AX ; environment block
- MOV AH,49H
- INT 21H
- ;
- ;Display copyright notice, then terminate and remain resident in memory.
- ;
- MOV AH,9 ;display copyright and hotkey
- MOV DX,OFFSET PROGRAM ; information
- INT 21H
- MOV AX,3100H
- MOV DX,(OFFSET INITIALIZE - OFFSET CODE + 15 + 128) SHR 4
- INT 21H
- INITIALIZE ENDP
-
- ;-----------------------------------------------------------------------------
- ; REMOVE deallocates the memory block addressed by ES and restores the
- ; interrupt vectors displaced on installation.
- ; Entry: ES - segment to release
- ; Exit: CF clear - program uninstalled
- ; CF set - can't uninstall
- ;-----------------------------------------------------------------------------
- REMOVE PROC NEAR
- MOV CX,ES ;abort if either interrupt
- MOV AX,3509H ; vector has been altered
- INT 21H ; since installation
- MOV AX,ES
- CMP AX,CX
- JNE REMOVE_ERROR
- MOV AX,3508H
- INT 21H
- MOV AX,ES
- CMP AX,CX
- JNE REMOVE_ERROR
- ;
- ;Free memory given to the original program block.
- ;
- MOV ES,CX ;Ask DOS to free it
- MOV AH,49H
- INT 21H
- JC REMOVE_ERROR ;exit if call failed
- ;
- ;Restore the interrupt 9h and 8h vectors to their installation values.
- ;
- PUSH DS
- ASSUME DS:NOTHING
- MOV AX,2509H ;restore interrupt 9h vector
- LDS DX,ES:[INT09H]
- INT 21H
- MOV AX,2508H ;restore interrupt 8h vector
- LDS DX,ES:[INT08H]
- INT 21H
- POP DS
- ASSUME DS:CODE
- NOT WORD PTR ES:[BEGIN] ;destroy ASCII fingerprint
- CLC ;clear CF for exit
- RET
- REMOVE_ERROR: STC ;set CF to indicate program
- RET ; couldn't be uninstalled
- REMOVE ENDP
-
- CODE ENDS
- END BEGIN
-